#ifndef GMSHIMPORT_HPP
#define GMSHIMPORT_HPP

#include "mesh.hpp"
#include "readMSH.hpp"
#include <fstream>
#include <string>
#include <vector>
#include <filesystem>

namespace hms::gmsh {

namespace fs = std::filesystem;

Mesh gmshToMesh( const fs::path& );

Mesh gmshToHms( std::istream& file );

auto nDomainCells( const MSH& ) -> Index;
auto nInnerEdges ( const MSH&, Index nBoundaryEdges ) -> Index;

auto collectNodes( const MSH& ) -> std::tuple<IdxVector, Matrix2Xs>;

auto collectDomainCellNodeTags( const MSH& msh, Index nDomainCells )
-> std::pair<
	Array4Xi,    /* node tags */
	ArrayX<char> /* number of node tags/vertices for each cell */
>;

auto boundaryPatchTags( const MSH& ) -> IdxVector;

auto boundaryEdgesPerPatch( const MSH&, const IdxVector& )
-> std::pair< Array2Xi, std::vector<ArrayXi> >;

Index tagToIndex( const IdxVector&, Index );
Index tagToIndex( Index, const IdxVector& );
template<Index rows>
void tagToIndex( Ref<ArrayNX<Index, rows>> m, const IdxVector& tags );
void tagToIndex( IdxVector& v, const IdxVector& tags );
/* for cells */
void tagToIndex(
	Ref<Array4Xi>, const Ref<const ArrayX<char>>&, const IdxVector&
);


auto createDomainCellEdges(
	const MSH& msh,
	const Ref<const Array4Xi>&  domainCellVertices,
	const Ref<const VectorX <char>>&  nDomainCellVertices,
	const Ref<const Array2Xi>& boundaryEdges
) -> std::pair<
	Array2Xi, /* vertex indices of all edges */
	Array4Xi  /* edge indices of domain cells */
>;


}
#endif